package com.shuqi.activity.viewport;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.ScrollView;

import java.util.ArrayList;
import java.util.List;

import com.shuqi.exception.ScrollException;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.ScrollView;


/**
 * 该类完美地解决了事件scrollview与Listview的事件冲突 无论向其中加入多少个Listview都不会造成影响
 * 
 * @author Administrator
 * 
 */
public class ListScrollView extends ScrollView {

    private List<ListView> list = new ArrayList<ListView>();

    private int scrollPaddingTop; // scrollview的顶部内边距
    private int scrollPaddingLeft;// scrollview的左侧内边距
    private int[] scrollLoaction = new int[2]; // scrollview在窗口中的位置

    private final static int UPGLIDE = 0; // 手指向上滑动对应的值
    private final static int DOWNGLIDE = 1;// 手指向下滑动对应的值
    private int glideState;// 对应滑动的状态

    public ListScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    private int downY = 0; // 第一下按下的坐标
    private int moveY = 0; // 移动时的坐标

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downY = (int) ev.getY();
                // System.out.println("actiondown" + ev.getY());
                break;
            case MotionEvent.ACTION_MOVE:
                moveY = (int) ev.getY();
                // System.out.println("move" + moveY + "down" + downY);
                if ((moveY - downY) >= 0) {
                    // System.out.println("'''''''''DOWNGLIDE'''''''''''");
                    glideState = DOWNGLIDE;
                } else {
                    // System.out.println("'''''''''UPGLIDE'''''''''''");
                    glideState = UPGLIDE;
                }
                break;
            case MotionEvent.ACTION_UP:
            default:
                break;
        }
        return super.dispatchTouchEvent(ev);
    }


    /**
     * 在传入事件的方法中 通过事件获取的XY的值 是相对于其容器而言的 比如该例子中容器为scrollview所以 在继承scrollview的类中所有对应的事件
     * 所取出的xy都是以scrollview所在的区域为取值区域 scrollview的左上角即为00
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // 该事件的xy是以scrollview的左上角为00点 而不是以窗口为00点
        int x = (int) ev.getX() + scrollLoaction[0];
        int y = (int) ev.getY() + scrollLoaction[1];
        for (int i = 0; i < list.size(); i++) {
            ListView listView = list.get(i);
            int[] location = new int[2];
            listView.getLocationInWindow(location);
            int width = listView.getWidth();
            int height = listView.getHeight();
            // 在listview的位置之内则可以滑动
            if (x >= location[0] + scrollPaddingLeft
                    && x <= location[0] + scrollPaddingLeft + width
                    && y >= location[1] + scrollPaddingTop
                    && y <= location[1] + scrollPaddingTop + height) {
                // System.out.println(glideState);
                // 在最底部则不可以在上拉
                if (((listView.getLastVisiblePosition() == (listView.getCount() - 1)) && (glideState == UPGLIDE))) {
                    // System.out.println("up");
                    break;
                }
                // 在最顶部则不可以在下拉
                if (((listView.getFirstVisiblePosition() == 0) && (glideState == DOWNGLIDE))) {
                    // System.out.println("down");
                    break;
                }
                return false; // 交给子控件直接处理
                              // 这时scrollview的ontouchevent将不能够在处理(实际上能不能够触发主要是有子view在处理事件时的返回值决定)
            }
        }
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return super.onTouchEvent(ev);
    }

    /**
     * 递归找出所有的listview
     * 
     * @param view
     */
    private void findAllListView(View view) {
        if (view instanceof ViewGroup) {
            int count = ((ViewGroup) view).getChildCount();
            for (int i = 0; i < count; i++) {
                if (!(view instanceof ListView)) {
                    findAllListView(((ViewGroup) view).getChildAt(i));
                }
            }
            if (view instanceof ListView) {
                list.add((ListView) view);
            }
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        scrollPaddingTop = getTop();
        scrollPaddingLeft = getLeft();
        getLocationInWindow(scrollLoaction);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        if (this.getChildCount() != 1) {
            try {
                throw new ScrollException();
            } catch (ScrollException e) {
                e.printStackTrace();
            }
        }
        list.clear();
        findAllListView(this.getChildAt(0));
    }

}
